package edu.bbu.commonproject.desktop.gui.view.swing.file.lister.components;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.TooManyListenersException;

import javax.swing.JPanel;

import edu.bbu.commonproject.desktop.gui.view.swing.file.lister.FileLister;
import edu.bbu.commonproject.desktop.gui.view.swing.utils.Design;

/**
 * The Lfile.
 */
public class LFile extends JPanel implements Listable
{	
	/** The name of the file. */
	protected String fileName;
	
	/** The file lister where it belong. */
	protected FileLister fileLister;
	
	/** The font of the file name. */
	protected Font labelFont;
	
	/** The fontmetrics of the file name font. */
	protected FontMetrics fontMetrics;
	
	/** Boolean value of the mouse if it is over the component. */
	protected boolean mouseOver = false;
	
	/** The drag source. */
	protected DragSource dragSource;
	
	/** The drop target. */
	protected DropTarget dropTarget;
	
	/** The extension. */
	protected String extension;
	
	/**
	 * The constructor.
	 * @param fileName the name of the file.
	 * @param fileLister the file lister where the file belong.
	 */
	public LFile(String fileName)
	{		
		dragSource = DragSource.getDefaultDragSource();
		
		dropTarget = new DropTarget();
		dropTarget.setActive(true);
		dropTarget.setComponent(this);
		dropTarget.setDefaultActions(DnDConstants.ACTION_COPY);
		
		
		this.fileName = fileName;
		int lastDotInName = fileName.lastIndexOf('.');
		
		if(lastDotInName != -1)
		{
			this.extension = fileName.substring(lastDotInName, fileName.length()).toUpperCase();
		}
		else 
		{
			this.extension = "";
		}
				
		this.labelFont = new Font("SansSerif", Font.BOLD, 12);
		this.fontMetrics = this.getFontMetrics(labelFont);

		setListener();
		
		this.setBackground(Color.WHITE);
		this.setPreferredSize(new Dimension(100,100));
	}
	
	/**
	 * Setting up the mouse listeners.
	 */
	private void setListener()
	{		
		this.addMouseListener(new MouseAdapter()
		{			
			public void mousePressed(MouseEvent e)
			{
				if(e.getClickCount() == 1)
				{
					setSelected();
				}
			}
			
			public void mouseEntered(MouseEvent e)
			{
				mouseOver = true;
				repaint();
			}
			
			public void mouseExited(MouseEvent e)
			{
				mouseOver = false;
				repaint();
			}
		});
	}
	
	/**
	 * Getting the file name.
	 * @return the file name.
	 */
	public String getItemName()
	{
		return fileName;
	}
	
	/**
	 * Setting the file name.
	 * @param directoryName the file name.
	 */
	public void setItemName(String fileName)
	{
		this.fileName = fileName;
	}
	
	/**
	 * It sets the file listener.
	 */
	public void setFileLister(FileLister fileLister)
	{
		this.fileLister = fileLister;
	}
	
	/**
	 * It gets the file listener.
	 */
	public FileLister getFileLister()
	{
		return fileLister;
	}
	
	/**
	 * Setting the selected object in the file lister.
	 */
	public void setSelected()
	{
		if(fileLister != null)
		{
			JPanel previouslySelected = (JPanel) fileLister.getSelectedListItem();
			fileLister.setSelectedListItem(this);
			
			if(previouslySelected != null)
			{
				previouslySelected.repaint();
			}
			
			mouseOver = false;
			repaint();
		}
	}
	
	/**
	 * It sets the unselected state.
	 */
	public void setUnSelected()
	{
		if(fileLister != null)
		{
			fileLister.setSelectedListItem(null);
			repaint();
		}
	}
	
	/**
	 * It gets the image.
	 */
	public Image getImage()
	{
		return Design.getFileTypeImage(extension);
	}

	/**
	 * It adds the drag gesture listener.
	 * @param dragGestureListener the drag gesture listener.
	 */
	public void addDragGestureListener(DragGestureListener dragGestureListener)
	{
		dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, dragGestureListener);
	}
	
	/**
	 * It adds the drop target listener.
	 * @param dropTargetListener the drop target listener.
	 */
	public void addDropTargetListener(DropTargetListener dropTargetListener)
	{
		try
		{
			dropTarget.addDropTargetListener(dropTargetListener);
		}
		catch (TooManyListenersException e) { }
	}
	
	/**
	 * The overrided painComponent.
	 */
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);		
		
		if (fileLister.getSelectedListItem() != this)
		{
			if (mouseOver)
			{
				g.drawImage(Design.FILELIST_MOUSEOVER, 0, 0, null);
			}
		}
		else
		{
			g.drawImage(Design.FILELIST_MOUSESELECTED, 0, 0, null);
		}
		
		g.drawImage(Design.getFileTypeImage(extension), 18, 8, null);

		Graphics2D g2d = (Graphics2D)g;
	    
	    g2d.setFont(labelFont);
	    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	    
	    int x = (100 - fontMetrics.stringWidth(fileName)) / 2;
	    
	    if(x < 0)
	    {
		    g2d.drawString(fileName, 0, 87);
	    }
	    else 
	    {
	    	g2d.drawString(fileName, x, 87);
	    }
	}
}
